#include "stdafx.h"
#include "CommandList.h"
#include "RegistryCommands.h"


CommandList::CommandList()
{
	m_commandMap.insert( std::make_pair( L"Quit", new QuitCommand() ) );
	m_commandMap.insert( std::make_pair( L"Exit", new QuitCommand() ) );
	m_commandMap.insert( std::make_pair( L"QueryObject", new QueryObjectCommand() ) );

	//	RegistryCommands.h
	m_commandMap.insert( std::make_pair( L"Close", new CloseCommand() ) );
	m_commandMap.insert( std::make_pair( L"CloseFile", new CloseCommand() ) );
	m_commandMap.insert( std::make_pair( L"CloseKey", new CloseCommand() ) );
	m_commandMap.insert( std::make_pair( L"CreateKey", new CreateKeyCommand() ) );
	m_commandMap.insert( std::make_pair( L"DeleteKey", new DeleteKeyCommand() ) );
	m_commandMap.insert( std::make_pair( L"DeleteValueKey", new DeleteValueKeyCommand() ) );
	m_commandMap.insert( std::make_pair( L"EnumKey", new EnumKeyCommand() ) );
	m_commandMap.insert( std::make_pair( L"EnumValueKey", new EnumValueKeyCommand() ) );
	m_commandMap.insert( std::make_pair( L"OpenKey", new OpenKeyCommand() ) );
	m_commandMap.insert( std::make_pair( L"OpenKeyEx", new OpenKeyExCommand() ) );
	m_commandMap.insert( std::make_pair( L"QueryKey", new QueryKeyCommand() ) );
	m_commandMap.insert( std::make_pair( L"QueryValueKey", new QueryValueKeyCommand() ) );
	m_commandMap.insert( std::make_pair( L"SetValueKey", new SetValueKeyCommand() ) );
}

CommandList::~CommandList()
{
}

//	Return true to indicate that the program should exit
bool CommandList::Execute( const wchar_t* pCommandLine )
{
	bool status = false;

	//	Handle a comment line
	if ( L'#' == *pCommandLine || L'\0' == *pCommandLine )
	{
		return false;
	}

	wchar_t* pTokContext;
	wchar_t* pModifiableCommandLine = _wcsdup( pCommandLine );
	if ( pModifiableCommandLine )
	{
		const wchar_t* pCommand = wcstok_s( pModifiableCommandLine, L" ", &pTokContext );
		if ( pCommand )
		{
			COMMAND_MAP_ITER it = m_commandMap.find( pCommand );
			if ( it != m_commandMap.end() )
			{
				BaseCommand* pCommandObj = it->second;

				//	Split the parameters into a vector
				const wchar_t* pParameter;
				const wchar_t* pValue;
				std::map<std::wstring, std::wstring> parameters;
				while ( NULL != ( pParameter = wcstok_s( NULL, L" ", &pTokContext ) ) )
				{
					if ( pParameter[0] != L'-' && pParameter[0] != L'/' )
					{
						break;
					}

					pValue = wcstok_s( NULL, L" ", &pTokContext );
					if ( !pValue )
					{
						break;
					}

					parameters.insert( std::make_pair( ++pParameter, pValue ) );
				}

				status = pCommandObj->Execute( parameters );
			}
			else
			{
				wprintf( L"Unrecognized command\n" );
			}
		}
		free( pModifiableCommandLine );
	}
	return status;
}
